// --- 0. 基础定义 (用于后续示例) ---

// 简单的 Performer 基类 (用于示例 1)
class BasePerformer {
  String name = "默认表演者";
  void perform() {
    print('$name 正在表演...');
  }
}

// 简单的 Person 基类 (用于示例 1)
class BasePerson {
  String name = "默认人";
}

// 简单的 Aggressive Mixin (用于示例 1)
mixin MixinAggressive {
  void beAggressive() {
    print("哼！有点小脾气！😠");
  }
}

// 简单的 Demented Mixin (用于示例 1)
mixin MixinDemented {
  void beDemented() {
    print("嘿嘿嘿...有点疯狂...🤪");
  }
}

// --- 1. Mixin 的基本使用 (with 关键字) ---

// 定义一个 Musical Mixin (示例 1 & 2 会用到类似概念，这里是示例1的版本)
mixin MixinMusical1 {
  bool canPlayPiano = false;
  bool canCompose = false;
  bool canConduct = false;

  void entertainMe() {
    print("--- MixinMusical1 的 entertainMe ---");
    if (canPlayPiano) {
      print('🎹 弹奏钢琴中...');
    } else if (canConduct) {
      print('指挥中... 👋');
    } else {
      print('自娱自乐地哼唱... 🎶');
    }
    print("----------------------------------");
  }
}

// 使用 Mixin 的 Musician 类
class MusicianClass1 extends BasePerformer with MixinMusical1 {
  MusicianClass1(String performerName) {
    name = performerName; // 设置继承自 BasePerformer 的 name
    canPlayPiano = true; // 设置来自 MixinMusical1 的属性
  }
  // MusicianClass1 自动拥有 perform() 和 entertainMe() 方法
}

// 使用多个 Mixin 的 Maestro 类
class MaestroClass extends BasePerson
    with MixinMusical1, MixinAggressive, MixinDemented {
  // Mixin 不能有构造函数，所以需要在 MaestroClass 的构造函数中初始化
  MaestroClass(String maestroName) {
    name = maestroName; // 设置继承自 BasePerson 的 name
    canConduct = true; // 设置来自 MixinMusical1 的属性
  }
  // MaestroClass 拥有来自 BasePerson 的 name, 以及三个 Mixin 的方法/属性
}

// --- 2. 在 Mixin 中定义抽象成员 (强制子类实现) ---

// 定义一个带抽象方法的 Mixin (这是示例2的 Musician Mixin)
mixin MixinMusician2 {
  // 抽象方法，使用此 Mixin 的类必须实现它
  void playInstrument(String instrumentName);

  // 具体方法，依赖于抽象方法
  void playPiano() {
    print("--- MixinMusician2 的 playPiano ---");
    playInstrument('钢琴'); // 调用必须由子类实现的 playInstrument
    print("---------------------------------");
  }

  void playFlute() {
    print("--- MixinMusician2 的 playFlute ---");
    playInstrument('长笛');
    print("---------------------------------");
  }
}

// 实现 MixinMusician2 的类
class VirtuosoClass with MixinMusician2 {
  // 必须实现 MixinMusician2 中的抽象方法
  @override
  void playInstrument(String instrumentName) {
    print('🎶 大师级地演奏 $instrumentName 中... 太好听了！');
  }
}

// --- 3. Mixin 访问子类状态 (通过抽象 getter) ---

// 定义一个依赖 name 属性的 Mixin
mixin MixinNameIdentity {
  // 抽象 getter，使用此 Mixin 的类必须有一个名为 name 的 String getter
  String get name;

  // 基于 name 实现 hashCode
  @override
  int get hashCode => name.hashCode;

  // 基于 name 实现 == 操作符
  @override
  bool operator ==(Object other) =>
      other is MixinNameIdentity && name == other.name;
}

// 使用 MixinNameIdentity 的类 (这是示例3的 Person 类)
class PersonClass2 with MixinNameIdentity {
  @override
  final String name; // 实现 Mixin 所需的 name getter (通过 final 字段)

  PersonClass2(this.name);

  // 这个类自动获得了基于 name 的 hashCode 和 == 实现
}

// --- 4. Mixin 实现接口 (约束子类) ---

// 定义一个接口 (也可以是抽象类)
abstract interface class TunerInterface {
  void tuneInstrument();
}

// 定义一个 Mixin，它声称实现了 TunerInterface，但实际上没有提供 tuneInstrument 的实现
// 这会强制使用此 Mixin 的类去实现 tuneInstrument
mixin MixinGuitarist implements TunerInterface {
  void playSong() {
    print("--- MixinGuitarist 的 playSong ---");
    tuneInstrument(); // 调用接口方法，需要子类来实现
    print('🎸 雄伟地弹奏吉他！ Rock n Roll!');
    print("--------------------------------");
  }

  // 注意：MixinGuitarist 没有实现 tuneInstrument
}

// 使用 MixinGuitarist 的类
class PunkRockerClass with MixinGuitarist {
  // 必须实现 MixinGuitarist 所依赖的 TunerInterface 的方法
  @override
  void tuneInstrument() {
    print("调音？不用麻烦了，跑调才是朋克摇滚！🤘");
  }
}

// --- 5. 使用 on 子句声明超类约束 ---

// 定义一个基础 Musician 类 (这是示例5的 Musician 类)
class MusicianClass3 {
  void musicianMethod() {
    print('(来自 MusicianClass3) 演奏音乐！🎵');
  }
}

// 定义一个 Mixin，它要求使用者必须是 MusicianClass3 的子类
// 这样 Mixin 内部就可以安全地使用 super 调用 MusicianClass3 的方法
mixin MixinMusicalPerformer on MusicianClass3 {
  void performerMethod() {
    print("--- MixinMusicalPerformer 的 performerMethod ---");
    print('(来自 MixinMusicalPerformer) 表演音乐！');
    super.musicianMethod(); // 安全地调用父类 (MusicianClass3) 的方法
    print("-------------------------------------------");
  }
}

// 这个类必须继承 MusicianClass3 才能使用 MixinMusicalPerformer
class SingerDancerClass extends MusicianClass3 with MixinMusicalPerformer {
  // 这个类自动拥有 musicianMethod 和 performerMethod
}

// 如果尝试在非 MusicianClass3 子类上使用 MixinMusicalPerformer 会报错
// class Actor with MixinMusicalPerformer {} // 编译错误

// --- 6. mixin class (既是 Mixin 也是 Class) ---

// 定义一个 mixin class (这是示例6的 Musician)
mixin class MusicianMixinClass {
  String instrument = "乐器";
  void play() {
    print("使用 $instrument 演奏中...");
  }

  // Mixin class 不能有 extends 或 with
  // Mixin class 不能有 on 子句
  // Mixin class 不能声明生成构造函数
}

// 将 MusicianMixinClass 作为 Mixin 使用
class NoviceAsMixin with MusicianMixinClass {
  NoviceAsMixin(String instrumentName) {
    instrument = instrumentName; // 可以访问和修改来自 mixin class 的成员
  }
}

// 将 MusicianMixinClass 作为 Class (父类) 使用
class NoviceAsClass extends MusicianMixinClass {
  NoviceAsClass(String instrumentName) {
    instrument = instrumentName;
  }
  // 可以重写父类方法
  @override
  void play() {
    print("新手正在笨拙地用 $instrument 演奏...");
  }
}

// --- Main Function ---
void main() {
  print('--- 1. 演示 Mixin 基本使用 ---');
  var musician1 = MusicianClass1("爱弹琴的乐手");
  musician1.perform();
  musician1.entertainMe();
  print('');

  var maestro = MaestroClass("疯狂指挥家");
  print('${maestro.name} 登场！');
  maestro.entertainMe();
  maestro.beAggressive();
  maestro.beDemented();
  print('');

  print('--- 2. 演示 Mixin 中的抽象成员 ---');
  var virtuoso = VirtuosoClass();
  virtuoso.playPiano();
  virtuoso.playFlute();
  print('');

  print('--- 3. 演示 Mixin 访问子类状态 ---');
  var personA = PersonClass2("张三");
  var personB = PersonClass2("李四");
  var personC = PersonClass2("张三");
  print('personA ($personA.name): hashCode=${personA.hashCode}');
  print('personB ($personB.name): hashCode=${personB.hashCode}');
  print('personC ($personC.name): hashCode=${personC.hashCode}');
  print('personA == personB: ${personA == personB}'); // false
  print('personA == personC: ${personA == personC}'); // true (因为 name 相同)
  print('');

  print('--- 4. 演示 Mixin 实现接口 ---');
  var punkRocker = PunkRockerClass();
  punkRocker.playSong();
  print('');

  print('--- 5. 演示 on 子句 ---');
  var singerDancer = SingerDancerClass();
  singerDancer.performerMethod(); // 会调用 Mixin 的方法和 super.musicianMethod()
  print('');

  print('--- 6. 演示 mixin class ---');
  var novice1 = NoviceAsMixin("小提琴");
  print('Novice (as Mixin):');
  novice1.play();
  print('');

  var novice2 = NoviceAsClass("三角铁");
  print('Novice (as Class):');
  novice2.play(); // 调用的是 NoviceAsClass 重写后的 play 方法
  print('');

  print('--- 所有 Mixin 演示完成 ---');
}
